package generic.interface1;

import java.util.Iterator;
import java.util.Random;
import java.util.function.Supplier;
import java.util.stream.Stream;

/**
 * 泛型接口
 * 可以编写一个类，实现 Supplier<Coffee> 接口，它能够随机生成不同类型的 Coffee 对象
 */
public class InterfaceGeneralization {
    public static void main(String[] args) {
        Stream.generate(new CoffeeSupplier())
                .limit(5)//没有这个limit会死循环
                .forEach(System.out::println);
        for(Coffee c:new CoffeeSupplier(5)) {
            System.out.println(c);
        }
    }
}
/**
 * java8提供了Supplier接口，java6可以自己实现简单next接口可以得到相同结果
 * 只能不能使用Stream方式处理问题
 * interface Generator<T> {T next();}
 */
class CoffeeSupplier implements Supplier<Coffee>,Iterable<Coffee> {

    private final Class<?>[] TYPES = { Latte.class, Mocha.class,
            Cappuccino.class, Americano.class, Breve.class };
    private static final Random RAND = new Random(47);

    public CoffeeSupplier() {}

    private int size = 0;

    public CoffeeSupplier(int size) {
        this.size = size;
    }

    @Override
    public Iterator<Coffee> iterator() {
        return new CoffeeIterator();
    }

    class CoffeeIterator implements Iterator<Coffee>{
        int count = size;
        @Override
        public boolean hasNext() {
            return count > 0;
        }

        @Override
        public Coffee next() {
            count--;
            return CoffeeSupplier.this.get();
        }

        @Override
        public void remove() {
            throw new UnsupportedOperationException();
        }
    }

    @Override
    public Coffee get() {
        try {
            return (Coffee)TYPES[RAND.nextInt(TYPES.length)].newInstance();
        } catch (InstantiationException|IllegalAccessException e) {
            throw new RuntimeException(e);
        }
    }

}

class Coffee {
    private static long counter = 0;
    private final long id = counter++;

    @Override
    public String toString() {
        return getClass().getSimpleName() + " " + id;
    }
}
class Latte  extends Coffee{}
class Mocha extends Coffee {}
class Cappuccino extends Coffee {}
class Americano extends Coffee {}
class Breve extends Coffee {}




